package com.qqim.common.utils;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;

/**
 * 文件操作工具类
 */
public class FileUtils {
    private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);
    
    private static final String USER_HOME = System.getProperty("user.home");
    private static final String APP_DIR = USER_HOME + File.separator + "QQIMChat";
    private static final String CACHE_DIR = APP_DIR + File.separator + "cache";
    private static final String IMAGE_DIR = CACHE_DIR + File.separator + "images";
    private static final String CHAT_DIR = CACHE_DIR + File.separator + "chats";
    
    static {
        // 初始化目录
        createDirectories();
    }
    
    /**
     * 创建应用所需目录
     */
    private static void createDirectories() {
        try {
            Files.createDirectories(Paths.get(APP_DIR));
            Files.createDirectories(Paths.get(CACHE_DIR));
            Files.createDirectories(Paths.get(IMAGE_DIR));
            Files.createDirectories(Paths.get(CHAT_DIR));
            logger.info("应用目录初始化成功: {}", APP_DIR);
        } catch (IOException e) {
            logger.error("创建应用目录失败", e);
        }
    }
    
    /**
     * 获取应用根目录
     */
    public static String getAppDir() {
        return APP_DIR;
    }
    
    /**
     * 获取缓存目录
     */
    public static String getCacheDir() {
        return CACHE_DIR;
    }
    
    /**
     * 获取图片缓存目录
     */
    public static String getImageDir() {
        return IMAGE_DIR;
    }
    
    /**
     * 获取聊天记录目录
     */
    public static String getChatDir() {
        return CHAT_DIR;
    }
    
    /**
     * 保存文件到指定路径
     */
    public static boolean saveFile(byte[] data, String filePath) {
        try {
            File file = new File(filePath);
            File parentDir = file.getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }
            
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write(data);
            }
            logger.info("文件保存成功: {}", filePath);
            return true;
        } catch (IOException e) {
            logger.error("保存文件失败: {}", filePath, e);
            return false;
        }
    }
    
    /**
     * 读取文件内容
     */
    public static byte[] readFile(String filePath) {
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                logger.warn("文件不存在: {}", filePath);
                return null;
            }
            
            try (FileInputStream fis = new FileInputStream(file)) {
                return IOUtils.toByteArray(fis);
            }
        } catch (IOException e) {
            logger.error("读取文件失败: {}", filePath, e);
            return null;
        }
    }
    
    /**
     * 保存图片文件
     */
    public static String saveImage(byte[] imageData, String originalFileName) {
        try {
            String extension = getFileExtension(originalFileName);
            String fileName = generateFileName("img", extension);
            String filePath = IMAGE_DIR + File.separator + fileName;
            
            if (saveFile(imageData, filePath)) {
                return filePath;
            }
        } catch (Exception e) {
            logger.error("保存图片失败", e);
        }
        return null;
    }
    
    /**
     * 图片转Base64字符串
     */
    public static String imageToBase64(String imagePath) {
        try {
            byte[] imageData = readFile(imagePath);
            if (imageData != null) {
                return Base64.getEncoder().encodeToString(imageData);
            }
        } catch (Exception e) {
            logger.error("图片转Base64失败: {}", imagePath, e);
        }
        return null;
    }
    
    /**
     * Base64字符串转图片
     */
    public static String base64ToImage(String base64Data, String extension) {
        try {
            byte[] imageData = Base64.getDecoder().decode(base64Data);
            String fileName = generateFileName("img", extension);
            String filePath = IMAGE_DIR + File.separator + fileName;
            
            if (saveFile(imageData, filePath)) {
                return filePath;
            }
        } catch (Exception e) {
            logger.error("Base64转图片失败", e);
        }
        return null;
    }
    
    /**
     * 保存聊天记录到文件
     */
    public static boolean saveChatHistory(String userId, String chatWithUserId, String content) {
        try {
            String fileName = generateChatFileName(userId, chatWithUserId);
            String filePath = CHAT_DIR + File.separator + fileName;
            
            // 追加模式写入聊天记录
            try (FileWriter writer = new FileWriter(filePath, true);
                 BufferedWriter bufferedWriter = new BufferedWriter(writer)) {
                
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String timestamp = sdf.format(new Date());
                String record = String.format("[%s] %s%n", timestamp, content);
                
                bufferedWriter.write(record);
                bufferedWriter.flush();
            }
            return true;
        } catch (IOException e) {
            logger.error("保存聊天记录失败", e);
            return false;
        }
    }
    
    /**
     * 读取聊天记录
     */
    public static String readChatHistory(String userId, String chatWithUserId) {
        try {
            String fileName = generateChatFileName(userId, chatWithUserId);
            String filePath = CHAT_DIR + File.separator + fileName;
            
            File file = new File(filePath);
            if (!file.exists()) {
                return "";
            }
            
            try (FileReader reader = new FileReader(file);
                 BufferedReader bufferedReader = new BufferedReader(reader)) {
                
                StringBuilder content = new StringBuilder();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    content.append(line).append("\n");
                }
                return content.toString();
            }
        } catch (IOException e) {
            logger.error("读取聊天记录失败", e);
            return "";
        }
    }
    
    /**
     * 生成聊天记录文件名
     */
    private static String generateChatFileName(String userId1, String userId2) {
        // 确保文件名的一致性，不管用户顺序
        String fileName = userId1.compareTo(userId2) < 0 
            ? userId1 + "_" + userId2 
            : userId2 + "_" + userId1;
        return fileName + "_chat.txt";
    }
    
    /**
     * 生成文件名
     */
    private static String generateFileName(String prefix, String extension) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
        String timestamp = sdf.format(new Date());
        String randomStr = String.valueOf(System.nanoTime() % 10000);
        return prefix + "_" + timestamp + "_" + randomStr + "." + extension;
    }
    
    /**
     * 获取文件扩展名
     */
    private static String getFileExtension(String fileName) {
        if (fileName == null || fileName.lastIndexOf('.') == -1) {
            return "";
        }
        return fileName.substring(fileName.lastIndexOf('.') + 1);
    }
    
    /**
     * 检查文件是否存在
     */
    public static boolean fileExists(String filePath) {
        return new File(filePath).exists();
    }
    
    /**
     * 删除文件
     */
    public static boolean deleteFile(String filePath) {
        try {
            File file = new File(filePath);
            if (file.exists()) {
                return file.delete();
            }
            return true;
        } catch (Exception e) {
            logger.error("删除文件失败: {}", filePath, e);
            return false;
        }
    }
    
    /**
     * 获取文件大小
     */
    public static long getFileSize(String filePath) {
        try {
            File file = new File(filePath);
            if (file.exists()) {
                return file.length();
            }
        } catch (Exception e) {
            logger.error("获取文件大小失败: {}", filePath, e);
        }
        return 0;
    }
} 